/**
 * IPC通信工具模块
 * 提供React组件与Electron主进程安全通信的工具函数，遵循React最佳实践
 * 实现进程间通信的错误处理、类型安全和用户友好的错误反馈机制
 */
import errorHandlerService from '../../services/errorHandlerService';

/**
 * IPC通信响应结果类型
 */
export interface IpcResponse<T = any> {
  success: boolean;
  data?: T;
  error?: string;
}

/**
 * 安全调用IPC的辅助函数
 * 封装Electron IPC invoke方法，提供类型安全的进程间通信机制
 * 支持错误捕获与用户通知，确保React组件能优雅处理IPC通信异常
 * 
 * @template T - 响应数据的类型
 * @param channel - IPC通道名称
 * @param data - 发送的数据（可选）
 * @param showNotification - 是否显示错误通知（默认：false）
 * @returns Promise<T> - 调用结果Promise
 * @throws 当IPC不可用或调用失败时抛出错误
 */
export const safeInvoke = async <T = any>(
  channel: string,
  data?: any,
  showNotification: boolean = false
): Promise<T> => {
  try {
    // 检查Electron IPC环境是否可用
    if (typeof window.electron === 'undefined' || !window.electron?.ipc) {
      const error = new Error('IPC通信环境不可用');
      console.error(`IPC通道[${channel}] - 环境检查失败:`, error);
      if (showNotification) {
        errorHandlerService.handleIpcError(error, channel);
      }
      throw error;
    }
    
    // 验证invoke方法是否存在且为函数类型
    if (typeof window.electron.ipc.invoke !== 'function') {
      const error = new Error('IPC invoke方法不可用');
      console.error(`IPC通道[${channel}] - 方法检查失败:`, error);
      if (showNotification) {
        errorHandlerService.handleIpcError(error, channel);
      }
      throw error;
    }
    
    // 执行IPC调用并返回结果
    console.debug(`执行IPC调用: ${channel}`);
    return await window.electron.ipc.invoke(channel, data);
  } catch (error) {
    console.error(`IPC通道[${channel}]调用失败:`, error);
    if (showNotification && error instanceof Error) {
      errorHandlerService.handleIpcError(error, channel);
    }
    throw error;
  }
};

/**
 * 安全发送IPC消息（单向）
 * 用于不需要响应的IPC通信场景，提供错误处理和验证
 * 
 * @param channel - IPC通道名称
 * @param data - 发送的数据（可选）
 * @returns boolean - 发送是否成功
 */
export const safeSend = (
  channel: string,
  data?: any
): boolean => {
  try {
    // 完善环境检查
    if (typeof window.electron === 'undefined' || !window.electron?.ipc || typeof window.electron.ipc.send !== 'function') {
      console.error(`IPC通道[${channel}] - send方法不可用`);
      return false;
    }
    
    console.debug(`发送IPC消息: ${channel}`);
    window.electron.ipc.send(channel, data);
    return true;
  } catch (error) {
    console.error(`IPC通道[${channel}]消息发送失败:`, error);
    return false;
  }
};

/**
 * 安全接收IPC消息
 * 为React组件提供安全的IPC事件监听机制
 * 
 * @param channel - IPC通道名称
 * @param listener - 事件监听器函数
 * @returns boolean - 监听是否成功设置
 */
export const safeReceive = (
  channel: string,
  listener: (...args: any[]) => void
): boolean => {
  try {
    // 完善环境检查
    if (typeof window.electron === 'undefined' || !window.electron?.ipc || typeof window.electron.ipc.receive !== 'function') {
      console.error(`IPC通道[${channel}] - receive方法不可用`);
      return false;
    }
    
    console.debug(`设置IPC消息监听: ${channel}`);
    window.electron.ipc.receive(channel, listener);
    return true;
  } catch (error) {
    console.error(`IPC通道[${channel}]设置监听失败:`, error);
    return false;
  }
};

/**
 * 安全移除IPC消息监听
 * 用于清理组件卸载时的事件监听，避免内存泄漏
 * 注意：根据实际Electron IPC API，移除监听器可能需要使用特定方法
 * 
 * @param channel - IPC通道名称
 * @param listener - 要移除的事件监听器函数（可选）
 * @returns boolean - 移除操作是否已尝试执行
 */
export const safeRemoveListener = (
  channel: string,
  listener?: (...args: any[]) => void
): boolean => {
  try {
    if (typeof window.electron === 'undefined' || !window.electron?.ipc) {
      console.error(`IPC通道[${channel}] - 环境不可用`);
      return false;
    }
    
    console.debug(`尝试移除IPC消息监听: ${channel}`);
    
    // 注意：根据TypeScript类型检查，window.electron.ipc可能没有removeListener方法
    // 在Electron渲染进程中，通常使用特定的方式移除监听器
    // 这里提供一个兼容方案，尝试使用可能存在的方法
    const ipc = window.electron.ipc as any;
    
    if (listener && ipc.removeListener) {
      ipc.removeListener(channel, listener);
    } else if (ipc.removeAllListeners) {
      ipc.removeAllListeners(channel);
    } else {
      console.warn(`当前环境下无法移除IPC通道[${channel}]的监听器，可能会导致内存泄漏`);
      // 即使无法移除，也返回true表示已经尝试过操作
    }
    
    return true;
  } catch (error) {
    console.error(`IPC通道[${channel}]移除监听失败:`, error);
    return false;
  }
};

/**
 * 检查IPC环境是否可用
 * @returns boolean - IPC环境是否可用
 */
export const isIpcAvailable = (): boolean => {
  return typeof window.electron !== 'undefined' && 
         window.electron?.ipc !== undefined &&
         typeof window.electron.ipc === 'object';
};

/**
 * 安全调用IPC的辅助函数（自动处理服务响应格式）
 * 专为处理服务层返回的{success, data, error}格式响应设计
 * 
 * @template T - 响应数据的类型
 * @param channel - IPC通道名称
 * @param data - 发送的数据（可选）
 * @param showNotification - 是否显示错误通知（默认：true）
 * @returns Promise<T> - 成功时返回data字段，失败时抛出错误
 */
export const safeInvokeService = async <T = any>(
  channel: string,
  data?: any,
  showNotification: boolean = true
): Promise<T> => {
  try {
    const response = await safeInvoke<IpcResponse<T>>(channel, data, false);
    
    // 检查响应格式和success状态
    if (!response || typeof response.success !== 'boolean') {
      throw new Error(`无效的服务响应格式: ${channel}`);
    }
    
    if (!response.success) {
      const errorMessage = response.error || `服务调用失败: ${channel}`;
      const error = new Error(errorMessage);
      if (showNotification) {
        errorHandlerService.handleIpcError(error, channel);
      }
      throw error;
    }
    
    return response.data as T;
  } catch (error) {
    console.error(`IPC服务调用[${channel}]失败:`, error);
    if (showNotification && error instanceof Error) {
      errorHandlerService.handleIpcError(error, channel);
    }
    throw error;
  }
};
